package com.aim.analysis.records;

import com.aim.util.MSE;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;

/**
 * User: Avraham Shvartzon
 * Date: 1/30/15
 */
public class PredictorUtil {

    public static <P> TreeMap<Double, P> bestParams(PerformancePredictor<P> predictor,
                                                    List<double[]> observations, List<P> candidates){

        List<double[]> testSet = new ArrayList<double[]>();
        List<double[]> trainingSet = new ArrayList<double[]>();
        int order = 0;
        System.out.println("I%2==" + order);
        for (int i = 0; i < observations.size(); i++) {
            if (i % 2 == order){
                trainingSet.add(observations.get(i));
            } else {
                testSet.add(observations.get(i));
            }
        }
        System.out.println("trainingSet size: " + trainingSet.size());
        System.out.println("testSet size: " + testSet.size());
        TreeMap<Double, P> error2Params = new TreeMap<Double, P>();

        for (P candidate : candidates) {
            predictor.setParameters(candidate);

            double sumError = calculateMSE(predictor, trainingSet);
            if (error2Params.containsKey(sumError) == false){
                error2Params.put(sumError, candidate);
            }
        }

        P value = error2Params.firstEntry().getValue();
        predictor.setParameters(value);
        System.out.println("test set error:\t" + calculateMSE(predictor, testSet));
        return error2Params;
    }

    private static <P> double calculateMSE(PerformancePredictor<P> predictor, List<double[]> observations) {
        double sumError = 0;
        for (double[] observation : observations) {
            double[] predict = predictor.predict(observation);
            double error = MSE.error(predict, observation);
            sumError += error;
        }
        return sumError /observations.size();
    }
}
